﻿using AutoMapper.Execution;
using Dm;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Formatters;
using SqlSugar;
using System.Diagnostics;
using System.Security.Claims;
using Zhao.Common.Helper;
using Zhao.IServer;
using Zhao.IServer.Events;
using Zhao.IServer.Management_Arena;
using Zhao.IServer.User;
using Zhao.Models.AppletDto;
using Zhao.Models.DTO;
using Zhao.Models.Entity;
using Zhao.Service.User;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Microsoft.AspNetCore.Http;
using Zhao.Arena.MiniProgram.Api.Utility.AuthorizationExt;

namespace Zhao.Arena.MiniProgram.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class ActivitesController : ControllerBase
    {
        private readonly IActivitiesServer _activitiesServer;
        private readonly IUsersServer _usersServer;
        private readonly IActivityMembersServer _activityMembersServer;
        private readonly IOrdersServer _ordersServer;
        private readonly IActivityMemberChangeOrdersServer _activityMemberChangeOrdersServer;
        private readonly IVenuesServer _venuesServer;

        public ActivitesController(
            IActivitiesServer activitiesServer, 
            IUsersServer usersServer, 
            IActivityMembersServer activityMembersServer, 
            IOrdersServer ordersServer, 
            IActivityMemberChangeOrdersServer activityMemberChangeOrdersServer,
            IVenuesServer venuesServer)
        {
            _activitiesServer = activitiesServer;
            _usersServer = usersServer;
            _activityMembersServer = activityMembersServer;
            _ordersServer = ordersServer;
            _activityMemberChangeOrdersServer = activityMemberChangeOrdersServer;
            _venuesServer = venuesServer;
        }


        /// <summary>
        /// 根据类型筛选活动
        /// </summary>
        /// <param name="date">日期</param>
        /// <param name="city">城市ID</param>
        /// <param name="area">区域ID</param>
        /// <param name="fType">类型ID</param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="searchaString">查询条件</param>
        /// <returns></returns>
        [HttpGet]
        [Route("{pageIndex:int}/{pageSize:int}/{date}")]
        [Route("{pageIndex:int}/{pageSize:int}/{date}/{fType:int}")]
        [Route("{pageIndex:int}/{pageSize:int}/{date}/{city:int}/{area:int}")]
        [Route("{pageIndex:int}/{pageSize:int}/{date}/{city:int}/{searchaString}")]
        [Route("{pageIndex:int}/{pageSize:int}/{date}/{fType:int}/{city:int}/{area:int}")]
        [Route("{pageIndex:int}/{pageSize:int}/{date}/{city:int}/{area:int}/{searchaString}")]
        [Route("{pageIndex:int}/{pageSize:int}/{date}/{fType:int}/{city:int}/{area:int}/{searchaString}")]
        public async Task<JsonResult> GetActivi(string date,int city=0,int area=0, int fType=0,int pageIndex =1,int pageSize=10, string searchaString = "")
        {
            PageModel<AppActivitiesDto> retsult = new PageModel<AppActivitiesDto>();

            if (!date.IsValidIsoDate())
            {
                date = DateTime.Today.ToString("yyyy-MM-dd");
            }

            Expressionable<Activities, Venues, FieldTypes> expressionable = new Expressionable<Activities, Venues, FieldTypes>();

            expressionable.AndIF(!searchaString.IsNullOrWhiteSpace(), (a, b, c) => a.Title.Contains(searchaString) || b.VenueName.Contains(searchaString));

            expressionable.And((a, b, c) => a.DisplayDate == date);

            expressionable.AndIF(fType != 0, (a, b, c) => a.TypeId == fType);

            expressionable.AndIF(city != 0, (a, b, c) => b.City == city);

            expressionable.AndIF(area != 0, (a, b, c) => b.Zone == area);

            retsult =await _activitiesServer.AppletActiviQueryAsync(expressionable.ToExpression(),pageIndex, pageSize);

            return new JsonResult(retsult);
        }



        /// <summary>
        /// 根据活动id获取详情
        /// </summary>
        /// <param name="keyId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("byId/{keyId:int}")]
        public async Task<JsonResult> GetActiviById(int keyId)
        {
            var result = new ApiResult<ActivitiesDetailedDto>
            {
                Success=false,
                Message="未查询到数据"
            };

            // 从Token中获取用户ID
            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;

            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限，请登录";
                return new JsonResult(result);
            }

            int userId = (int)idClaim.ToInt32();

            var data =await _activitiesServer.AppleActiviGetById(keyId,userId);

            if (data != null)
            {
                result.Success = true;
                result.Message = "查询成功";
                result.Data = data;
            }
            return new JsonResult(result);
        }


        /// <summary>
        /// 获取用户的报名情况
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("RegisterInfo/{aId:int}")]
        [Authorize]
        public async Task<JsonResult> GetRegisterInfo(int aId)
        {
            var result = new ApiResult<ActivityInfoDto>
            {
                Success = false,
                Message = "未查询到数据"
            };

            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;

            //获取到id
            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限,请登录";
                return new JsonResult(result);
            }

            int userId = (int)idClaim.ToInt32();

            //获取活动
            var activity =await _activitiesServer.QueryAsync(aId);

            //获取用户信息
            var user = await _usersServer.QueryAsync(userId);
            
            //获取用户的报名信息
            var activityMembers= await _activityMembersServer.QueryAsync(x=>x.ActivityId== aId && x.UserId==userId && x.Status == 1);

            //获取报名信息
            var totalSum = await _activityMembersServer.QueryListAsync(x => x.ActivityId == aId && x.Status == 1);

            DateTime combinedDateTime = activity.DisplayDate.GetCombinedDateTime(activity.StartTime); // 将日期和时间合并

            result.Data = new ActivityInfoDto
            {
                MaxNumber = activity.MaxNumber,
                SunNumber= totalSum.Sum(x=>x.MaleNumber + x.FemaleNumber),
                Phone=user.Phone,
                Name=user.Username,
                Price=activity.Price,
                StartTime= combinedDateTime,
                Deadline=activity.Deadline,
                MaleNumber=activityMembers==null?default:activityMembers.MaleNumber,
                FemaleNumber=activityMembers==null?default:activityMembers.FemaleNumber,
                PriceType = activity.PriceType,
                IsLadyDiscountEnabled = activity.IsLadyDiscountEnabled,
                LadyDiscountType = activity.LadyDiscountType,
                LadyDiscountValue = activity.LadyDiscountValue
            };

            if (result.Data != null)
            {
                result.Success = true;
                result.Message = "查询成功";
            }

            return new JsonResult(result);
        }



        /// <summary>
        /// 活动报名
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Apply")]
        [Authorize]
        public async Task<JsonResult> Apply([FromBody] ApplyDto dto)
        {
            var result = new ApiResult { Success = false };

            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;

            //获取到id
            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限,请登录";
                return new JsonResult(result);
            }

            int userId = (int)idClaim.ToInt32();

            dto.UId = userId;
            dto.Number = dto.MaleNumber+dto.FemaleNumber; // 确保总人数正确

            // 1. 查询活动
            var activity = await _activitiesServer.QueryAsync(dto.AId);
            if (activity == null)
            {
                result.Message = "活动不存在";
                return new JsonResult(result);
            }

            // 2. 校验活动是否已开始
            DateTime startDateTime = activity.DisplayDate.GetCombinedDateTime(activity.StartTime);
            if (DateTime.Now >= startDateTime)
            {
                result.Message = "活动已开始，无法报名";
                return new JsonResult(result);
            }

            // 3. 校验报名人数是否已满
            var totalMembers = await _activityMembersServer.QueryListAsync(x => x.ActivityId == dto.AId && x.Status == 1 );
            int currentCount = totalMembers.Sum(x => x.MaleNumber + x.FemaleNumber);
            if (activity.MaxNumber!=0 &&currentCount + dto.Number > activity.MaxNumber)
            {
                result.Message = "报名人数已满或超出最大人数";
                return new JsonResult(result);
            }

            // 4. 查询用户
            var user = await _usersServer.QueryAsync(userId);
            if (user == null)
            {
                result.Message = "用户不存在";
                return new JsonResult(result);
            }

            // 5. 根据定价类型计算实际费用
            decimal actualPrice = 0;
            switch (activity.PriceType)
            {
                case 1: // 固定价
                    // 男性按原价计算
                    decimal malePrice = activity.Price * dto.MaleNumber;
                    
                    // 女性按优惠价计算
                    decimal femalePrice = 0;
                    if (activity.IsLadyDiscountEnabled && dto.FemaleNumber > 0)
                    {
                        switch (activity.LadyDiscountType)
                        {
                            case 1: // 固定价
                                femalePrice = activity.LadyDiscountValue.GetValueOrDefault() * dto.FemaleNumber;
                                break;
                            case 3: // 折扣
                                femalePrice = activity.Price * activity.LadyDiscountValue.GetValueOrDefault() * dto.FemaleNumber;
                                break;
                            case 5: // 减价
                                decimal discountedPrice = activity.Price - activity.LadyDiscountValue.GetValueOrDefault();
                                discountedPrice = discountedPrice < 0 ? 0 : discountedPrice;
                                femalePrice = discountedPrice * dto.FemaleNumber;
                                break;
                            default:
                                femalePrice = activity.Price * dto.FemaleNumber;
                                break;
                        }
                    }
                    else
                    {
                        // 如果未启用女士优惠，按原价计算
                        femalePrice = activity.Price * dto.FemaleNumber;
                    }
                    
                    // 总价 = 男性价格 + 女性价格
                    actualPrice = malePrice + femalePrice;
                    break;
                    
                case 3: 
                    // AA制男女生收取的押金一致 只有在结算的时候按照实际的价钱优惠
                    // AA制中，使用DepositAmount字段作为每人押金，按人头收取
                    decimal depositPerPerson = activity.DepositAmount ?? 0;
                    //男生押金
                     actualPrice = depositPerPerson * (dto.MaleNumber+ dto.FemaleNumber);
                    break;
                    
                case 5: // 免费
                    actualPrice = 0;
                    break;
                    
                default:
                    actualPrice = activity.Price * dto.Number; // 默认按固定价处理
                    break;
            }

            // 6. 校验余额
            if (actualPrice > 0 && user.AccountBalance < actualPrice)
            {
                result.Message = "余额不足";
                return new JsonResult(result);
            }

            await _usersServer.UpdateAsync(user);

            // 7. 调用服务层报名
            var applyResult = await _activitiesServer.ApplyActivityAsync(dto);
            if (applyResult)
            {
                result.Success = true;
                result.Message = "报名成功";
            }
            else
            {
                result.Message = "报名失败";
            }
            return new JsonResult(result);
        }


        /// <summary>
        /// 修改报名信息
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("UpdateApply")]
        [Authorize]
        public async Task<JsonResult> UpdateApply([FromBody] ApplyDto dto)
        {
            var result = new ApiResult { Success = false };

            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;

            //获取到id
            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限,请登录";
                return new JsonResult(result);
            }

            int userId = (int)idClaim.ToInt32();

            dto.UId = userId;
            dto.Number = dto.MaleNumber + dto.FemaleNumber; // 确保总人数正确

            if (dto == null || dto.AId <= 0 || dto.UId <= 0 || dto.Number <= 0)
            {
                result.Message = "参数无效";
                return new JsonResult(result);
            }

            // 查询活动
            var activity = await _activitiesServer.QueryAsync(dto.AId);
            if (activity == null)
            {
                result.Message = "活动不存在";
                return new JsonResult(result);
            }

            // 查询用户
            var user = await _usersServer.QueryAsync(userId);
            if (user == null)
            {
                result.Message = "用户不存在";
                return new JsonResult(result);
            }

            // 查询当前报名信息
            var member = await _activityMembersServer.QueryAsync(x => x.ActivityId == dto.AId && x.UserId == dto.UId && x.Status == 1);
            if (member == null)
            {
                result.Message = "未找到报名信息";
                return new JsonResult(result);
            }

            int oldMaleNumber = member.MaleNumber;
            int oldFemaleNumber = member.FemaleNumber;
            int oldNumber = oldMaleNumber + oldFemaleNumber;
            int diff = dto.Number - oldNumber;
            

            result = await _activitiesServer.UpdateApplyInfoAsync(dto, oldNumber, user);
            return new JsonResult(result);
        }


        /// <summary>
        /// 取消报名
        /// </summary>
        /// <param name="dto">取消报名信息</param>
        /// <returns></returns>
        [HttpPost]
        [Route("CancelApply")]
        [Authorize]
        public async Task<JsonResult> CancelApply([FromBody] CancelApplyDto dto)
        {
            var result = new ApiResult { Success = false };

            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;

            //获取到id
            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限,请登录";
                return new JsonResult(result);
            }

            int userId = (int)idClaim.ToInt32();
            dto.UserId = userId;

            if (dto == null || dto.ActivityId <= 0 )
            {
                result.Message = "参数无效";
                return new JsonResult(result);
            }

            // 查询活动
            var activity = await _activitiesServer.QueryAsync(dto.ActivityId);
            if (activity == null)
            {
                result.Message = "活动不存在";
                return new JsonResult(result);
            }

            // 校验活动是否已开始
            DateTime startDateTime = activity.DisplayDate.GetCombinedDateTime(activity.StartTime);
            if (DateTime.Now >= startDateTime)
            {
                result.Message = "活动已开始，无法取消报名";
                return new JsonResult(result);
            }

            // 校验是否超过取消报名截止时间
            if (activity.Deadline != default)
            {
                double deadline = (double)activity.Deadline;
                DateTime cancelDeadline = startDateTime.AddHours(-deadline);
                if (DateTime.Now >= cancelDeadline)
                {
                    result.Message = $"活动开始前{activity.Deadline}小时内禁止取消报名";
                    return new JsonResult(result);
                }
            }

            // 查询用户
            var user = await _usersServer.QueryAsync(userId);
            if (user == null)
            {
                result.Message = "用户不存在";
                return new JsonResult(result);
            }

            // 查询报名信息
            var member = await _activityMembersServer.QueryAsync(x => x.ActivityId == dto.ActivityId && x.UserId == dto.UserId && x.Status == 1);
            if (member == null)
            {
                result.Message = "未找到报名信息";
                return new JsonResult(result);
            }

            // 查询原订单
            var oldOrder = await _ordersServer.QueryAsync(o => o.UserId == dto.UserId && o.ActivityId == dto.ActivityId && o.Status == 3);

            if (oldOrder == null)
            {
                result.Message = "未找到订单信息";
                return new JsonResult(result);
            }

            result = await _activitiesServer.CancelApplyAsync(dto, member, oldOrder, user);
            return new JsonResult(result);
        }

        /// <summary>
        /// 获取用户参与的活动列表
        /// </summary>
        /// <returns>
        /// 用户活动列表，包括：
        /// 1. 进行中的活动（OngoingActivities）
        /// 2. 已完成的活动（CompletedActivities）
        /// 3. 已取消的活动（CancelledActivities）
        /// 
        /// 每个活动包含以下信息：
        /// - 基本信息（ID、标题、日期、时间、状态等）
        /// - 报名人数（男性、女性、总人数）
        /// - 价格信息（价格类型、原始价格、押金金额）
        /// - 女性优惠信息（是否启用、优惠类型、优惠值、优惠说明）
        /// - 支付信息（实际支付金额、退款金额、最终支付金额）
        /// - 场馆信息（名称、地址）
        /// - 订单ID
        /// </returns>
        [HttpGet]
        [Route("user-activities")]
        [Authorize]
        public async Task<JsonResult> GetUserActivities()
        {
            var result = new ApiResult<UserActivityListDto>
            {
                Success = false,
                Message = "获取数据失败"
            };

            // 从Token中获取用户ID
            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;

            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限，请登录";
                return new JsonResult(result);
            }

            int userId = (int)idClaim.ToInt32();

            try
            {
                // 调用服务层方法获取用户活动列表
                var activities = await _activitiesServer.GetUserActivitiesAsync(userId);

                result.Success = true;
                result.Message = "获取成功";
                result.Data = activities;
            }
            catch (Exception ex)
            {
                result.Message = "获取数据失败：" + ex.Message;
            }

            return new JsonResult(result);
        }

        /// <summary>
        /// 创建活动
        /// </summary>
        /// <param name="dto">活动信息</param>
        /// <returns>创建结果</returns>
        [HttpPost]
        [Route("create")]
        [Authorize]
        public async Task<JsonResult> CreateActivity([FromBody] ActivityCreateDto dto)
        {
            var result = new ApiResult { Success = false };

            // 验证必填参数
            if (dto == null)
            {
                result.Message = "请求数据无效";
                return new JsonResult(result);
            }

            if (string.IsNullOrWhiteSpace(dto.Title))
            {
                result.Message = "活动标题不能为空";
                return new JsonResult(result);
            }

            if (string.IsNullOrWhiteSpace(dto.Description))
            {
                result.Message = "活动描述不能为空";
                return new JsonResult(result);
            }

            if (string.IsNullOrWhiteSpace(dto.DisplayDate) || !dto.DisplayDate.IsValidIsoDate())
            {
                result.Message = "活动日期格式无效";
                return new JsonResult(result);
            }

            if (dto.MaxNumber <= 0)
            {
                result.Message = "最大参与人数必须大于0";
                return new JsonResult(result);
            }

            if (dto.Price < 0)
            {
                result.Message = "活动价格不能为负数";
                return new JsonResult(result);
            }

            if (string.IsNullOrWhiteSpace(dto.Image))
            {
                result.Message = "活动封面图片不能为空";
                return new JsonResult(result);
            }

            // 获取当前用户ID
            string? idClaim = User?.Claims?.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Sid))?.Value;
            if (idClaim.IsNullOrWhiteSpace())
            {
                result.Message = "无权限，请登录";
                return new JsonResult(result);
            }
            int userId = (int)idClaim.ToInt32();

            // 获取用户所属球馆
            // 调用VenueController的接口获取用户关联的球馆
            var myVenueResponse = await GetMyVenueInfo(userId);
            if (!myVenueResponse.Success || myVenueResponse.Data == null)
            {
                result.Message = "您尚未成功入驻球馆，无法发布活动";
                return new JsonResult(result);
            }

            Guid venueId = myVenueResponse.Data.VenueId;

            // 调用服务层创建活动
            result = await _activitiesServer.CreateActivityAsync(dto, venueId, userId);

            return new JsonResult(result);
        }

        /// <summary>
        /// 获取活动类型列表
        /// </summary>
        /// <returns>活动类型列表</returns>
        [HttpGet]
        [Route("types")]
        public async Task<JsonResult> GetActivityTypes()
        {
            var result = new ApiResult<List<FieldTypeOption>> { Success = false };

            try
            {
                // 使用服务层中的查询方法
                var types = await _activitiesServer.GetFieldTypesAsync();
                
                result.Data = types;
                result.Success = true;
                result.Message = "获取成功";
            }
            catch (Exception ex)
            {
                result.Message = "获取活动类型失败：" + ex.Message;
            }

            return new JsonResult(result);
        }

        /// <summary>
        /// 获取当前用户关联的球馆信息（辅助方法）
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>球馆信息</returns>
        private async Task<ApiResult<VenueInfoDto>> GetMyVenueInfo(int userId)
        {
            var result = new ApiResult<VenueInfoDto> { Success = false };
            
            try
            {
                // 查询用户关联的申请记录
                var applications = await _venuesServer.GetUserApplications(userId);
                if (applications == null || !applications.Any() || !applications.First().VenunId.HasValue)
                {
                    result.Message = "未找到球馆信息";
                    return result;
                }
                
                var venueId = applications.First().VenunId.Value;
                
                // 查询球馆详情
                var venue = await _venuesServer.QueryAsync(v => v.VenueID == venueId);
                if (venue == null)
                {
                    result.Message = "球馆信息不存在";
                    return result;
                }
                
                // 构建返回数据
                result.Data = new VenueInfoDto
                {
                    VenueId = venue.VenueID,
                    VenueName = venue.VenueName,
                    Images = venue.Images,
                    OpenTime = venue.OpenTime.ToString(),
                    CloseTime = venue.CloseTime.ToString(),
                    Address = venue.Address,
                    ContactPhone = venue.ContactPhone,
                    ManagerName = venue.ManagerName,
                    Description = venue.Description,
                    ReservationRules = venue.ReservationRules,
                    Province = venue.Province,
                    City = venue.City,
                    Zone = venue.Zone
                };
                
                result.Success = true;
                result.Message = "获取球馆信息成功";
            }
            catch (Exception ex)
            {
                result.Message = "获取球馆信息失败：" + ex.Message;
            }
            
            return result;
        }

        /// <summary>
        /// 取消活动（球馆管理员使用）
        /// </summary>
        /// <param name="id">活动ID</param>
        /// <param name="request">取消原因请求</param>
        /// <returns>操作结果</returns>
        [HttpPatch("cancel/{id}")]
        [Authorize(Policy = "VenueManager")]
        public async Task<JsonResult> CancelActivity(int id, [FromBody] CancelActivityRequest request)
        {
            // 获取操作人ID
            string? userIdClaim = User.FindFirst("UserId")?.Value;
            int operatorId = 0;
            int.TryParse(userIdClaim, out operatorId);
            
            // 获取球馆ID
            string? venueIdClaim = User.FindFirst("VenueId")?.Value;
            Guid venueId = Guid.Empty;
            Guid.TryParse(venueIdClaim, out venueId);
            
            // 检查活动是否存在
            var activity = await _activitiesServer.QueryAsync(x => x.ActivityID == id);
            if (activity == null)
            {
                return new JsonResult(new ApiResult 
                { 
                    Success = false,
                    Message = "活动不存在" 
                });
            }
            
            // 验证权限（只能取消自己球馆的活动）
            if (activity.VenueID != venueId)
            {
                return new JsonResult(new ApiResult 
                { 
                    Success = false,
                    Message = "无权取消此活动" 
                });
            }
            
            // 执行取消活动操作
            var result = await _activitiesServer.CancelActivityAsync(id, operatorId, request.CancelReason);
            
            return new JsonResult(result);
        }
    }
}
